package com.tedu.API;


import org.junit.Test;

import java.util.Scanner;

/**
 * JavaSE:  基础语法, JavaOOP面向对象编程, JavaAPI(帮助文档，理解:字典)
 *
 * JavaAPI【内置】 提供大量类、接口、抽象类、异常、错误
 * 【预计提供好的类库  8000, JavaAPI只学习重点】
 *
 * JavaAPI: 字符串  包装类  集合【泛型】、线程、
 *          多线程、【并发--大数据】、IO流、Socket套接字【网络编程】
 *
 * jdk1.8.chm帮助文档     理解:  新华字典   会查类、接口、抽象...使用
 * JDK版本---帮助文档   根据用什么JDK，查对应版本帮助文档
 * 必须会查API     String类---什么包下?
 *                java.lang【默认:不需要导包】
 *
 * JDK1.8  StringAPI类库: 构造器怎么用，方法怎么用?
 *
 */
public class StringAPI {
    /**
     * JDK1.8  StringAPI类库: 构造器怎么用，方法怎么用?
     * 包位置: java.lang 【不需要导入包: System String】
     * java: 错误: 无效的源发行版: 17
     * maven项目: 自动下载: junit版本---testing级别【识别JDK17】
     * 调整maven项目jdk版本: 17版本降级1.8版本
     * 找到pom.xml---17
     * 特点: 不需要导入包、不可以继承、字符数组、定义完毕无法修改
     * 修改可以覆盖，String类是final、java字符串编码集
     * 顶级UniCode: GBK UTF-8: 任何字符对应2个字节!
     * 字符串底层: 封装了字符数组及针对字符数组的操作算法
     * 字符数组===字符串
     * 定义:String str="直接量";  给定值创建String字符串新对象
     * String str=new String(); 创建String字符串对象
     */
    @Test
    public void testString() {
        String str = "字符串";
        System.out.println(str);
        char[] c = {'字', '符', '串'};   //字符串数组---静态字符串数组
        System.out.println(c);
        //字符串创建出来，无法修改，因为String是final修饰
        String s = "Hello World";
        s = "123";   //对对象进行覆盖
        System.out.println(s);
    }

    /*
     *  String常量池:
     * 定义给定值的方法: String str="java123"
     * Java为了提高性能，针对静态字符串(字面量/常量/两者连接后的结果)
     * 创建在String常量池中，对于重复创建静态字符串，JVM虚拟机首先
     * 会在常量池中查找，如果找到就返回对象，找不到继续创建新对象!
     *
     * JVM会在虚拟机的堆内存中开辟一块空间，保存曾经使用过的字面量|常量
     * 一旦后期又使用相同的字面量|常量，不会创建新对象，直接使用老对象
     *
     * 好处: 减少内存开销，提高性能
     */
    @Test
    public void testStrings() {
        String s1 = "java123";  //公共常量池
        String s2 = "java123";  //不会创建对象，从常量池java123
        System.out.println(s1 == s2);  //true
        String s = "java";  //s对象  不可修改
        String s3 = s + "123";  //s3对象=s对象+"123";   s3新对象
        System.out.println(s1 == s3);  //java123 == java123  true
        String s4 = "java" + "123";
        //右侧: 直接量方式拼接，静态字符串，存入常量池中
        System.out.println(s2 = s4);   //true
        //s2的java123从常量池中获取，s4拼接后静态字符串，从常量池获取
        //----------上面的代码: 给定值定义字符串方式: 拥有常量池-----
        //----------下面的代码: 创建字符串方式-----
        String s5 = new String("java123");
        //new 出来的对象一定是新对象，不存在常量池
        System.out.println(s4 = s5);
    }

    /**
     * String API  方法
     * length方法     返回值：int
     * 作用: 返回当前字符串的长度(个数)---借鉴于数组length方法
     * 特点: 字符串包含: 特殊字符空格、字母、汉字
     * String对象采用Uincode顶级编码: 每个字符串算一个，占两个字节
     */
    @Test
    public void testLength() {
        String str = "Hello World";  //11
        System.out.println(str.length());
        str = "我爱java";
        System.out.println(str.length());  //7
    }

    /**
     * indexOf方法  --- 重载功能: 修饰符  返回值   方法名  一致
     *                                         参数   不一致
     * indexOf(int index)   返回值: int
     * 第一个参数int index:传入指定字符串
     * 作用: 查找指定字符串在当前字符串中位置，首位置，
     * 如果匹配到对应字符，输出首位置下标，
     * 如果没有匹配对应字符，返回-1值
     * indexOf(String str,int index)   返回值: int
     * 第一个参数String str:传入指定字符串
     * 第二个参数int index: 查找指定具体位置的下标
     * 作用: 查找具体的下标位置的“字符串”在"当前字符串"中位置，首位置，
     * 如果查找相同名称，向下查找，不包含当前位置
     * 如果没有匹配对应字符，返回-1值
     * lastIndexOf(String str)方法
     * 作用: 找到匹配字符串中对应最后出现子字符串位置
     */
    @Test
    public void testIndexOf() {
        String str = "thinking in java";  //java编程思想【第四版】
        //返回值: 下标位
        int index = str.indexOf("ja");  //用处: 查找第一位相同
        System.out.println("打印下标位: " + index);
        index = str.indexOf("in", 6);
        //用处: 查找指定某一位相同
        System.out.println("指定下标位: " + index);
        //lastIndeOf()找到最后一次出现的下标位置
        index = str.lastIndexOf("in");
        System.out.println("最后的下标位: " + index);
    }

    /**
     * StringAPI针对字符串提供三种方法: 截取、替换、过滤、分割【常用方法】
     * subString方法  截取  返回值: String
     * subString(int start,int end)
     * 作用: 截取字符串,从下标start位置开始截取，截取到end下标位置
     * subString(int index)方法
     * 作用: 截取字符串，从下标index位置开始截取，截取到最后
     * 通用口诀: 含头不含尾
     */
    @Test
    public void testSubString() {
        String url = "www.baidu.com";  //需求: 通过截取字符串当中的baidu
        //url=url.substring(4,9);  // .baidu.  (3,10)  .co  (9,12)
        System.out.println("截取子字符串: " + url);
        //需求: 通过截取字符串  .com
        url = url.substring(9);
        System.out.println("截取子字符串，截取到最后" + url);
    }

    /**
     *  charAt方法   返回值: char
     *  作用: 返回当前位置字符串中指定位置的字符
     *  StringIndexOutBoundException  异常
     *  字符串下标越界异常---出现原因: 下标超出范围
     */
    @Test
    public void testCharAt(){
        String str="thinking in java";
        char c=str.charAt(15);
        System.out.println("获取到对应的字符: "+c);
    }

    /**
     * trim方法 返回值  String
     * 作用: 去掉当前字符串的前后空格【转大小叠加使用】
     * 统一转换大小写，去掉空格之后
     *
     * toLowerCase方法   返回值String
     * 作用:将字符串中所有字符转换为小写
     * toUpperCase方法   返回值String
     * 作用:将字符串中所有字符转换为大写
     * 验证码: xD4e    前台显示: xD4e    用户输入: xd4e
     */
    @Test
    public void testTrim(){
        String str="xD4e";  //后台传入前后加空格，xD4e判断
        //后台传入前台字符串----一律空
        str=str.trim().toLowerCase();
        System.out.println("去掉空格: "+str);
    }

    /**
     * match(String regex):
     * 【PHP---前端】正则表达式: 语法---元字符   ^ [0~9]*$
     *     验证字符串
     *   matches方法
     *   作用: 用于验证字符串，使用正则表达式进行验证【过滤字符】
     *        返回true正则验证通过成功，返回false正则验证失败
     */
    public static void main(String[] args) {
        String regex="^\\d{15}|\\d{18}$";
        System.out.println("请输入: ");
        //从控制台输出【模拟用户输入】  "123"
        Scanner input=new Scanner(System.in);
        //判断，如果正则通过，返回是数字，反之相反
        if(input.nextLine().matches(regex)){
            System.out.println("是正确身份证号");
        }else{
            System.out.println("不是正确身份证号");}
        //String regex="^[0-9]*$";  //匹配所有的0-9的数值
       // System.out.println("请输入: ");
        //从控制台输出【模拟用户输入】
        //Scanner input=new Scanner(System.in);
        //判断，如果正则通过，返回是数字，反之相反
       // if(input.nextLine().matches(regex)){
        //    System.out.println("是数字");
       // }else{
       //     System.out.println("不是数字~");
       // }
    }

    /**
     * replace方法:  替换   返回值: String
     * replace(String a,String b)
     * 第一步参数   String a 传入替换字符
     * 第二步参数   String b 传入查找字符
     * 作用: 用于匹配字符串中存在字符，匹配成功，替换成新字符，
     *       不支持正则
     *
     *
     * replaceAll(String regex,String a)
     * 作用: 用于全部匹配字符串中存在字符，按照正则进行匹配，
     *       匹配成功，替换成新字符，支持正则
     *
     */
    @Test
    public void testReplace(){
        String str="我爱Java";  //需求: Java替换Python
        str=str.replace("java","Python");
        //                 替换的字符             查找的字符
        System.out.println("替换后的字符串: "+str);

        String regex="^[\\u4e00-\\u9fa5]{0,}$";  //验证汉字
        String say="食物语陪伴版";
        say=say.replaceAll(regex,"******");  //支持正则
        System.out.println("通过正则替换后的字符串: "+say);
    }

    /**
     * split方法    分割   返回值: String[]
     * 作用: 用于按照"正则"或者"字符串"的方式分隔字符串
     *   www.baidu.com     按照.的方式获取
     *   split写.  代表正则表达式: .   匹配一个字符
     *   split写.  注意: 转义成 \\.
     */
    @Test
    public void testSplit(){
        String url="www.baidu.com";   //不知道下标的情况下，获取baidu
        String[] urls=url.split("\\.");
        System.out.println("获取元素值: "+urls[1]);  //获取baidu
        //思考: 代码哪里出现错误  ArrayIndexOutOfBoundsException
        // 打印字符串数组--增强for  数组数据类型  引用: 遍历数组引用
        for(String s:urls){
            System.out.println("分割后的元素值: "+s);
        }
    }

    /**
     * valueOf()   静态方法:通过类名访问    返回值: String
     * 作用: 基础数据类型转换为字符串
     */
    @Test
    public void testValueOf(){
        int i=123;   //基础数据类型转换为字符
        String s=String.valueOf(i);
        if(s.equals("123")){  //  s对象==="123"   判断对象 false
            // s对象.equals("123")  判断对象的值  true 没有实际值判断对象
            System.out.println("是字符串");
        }else{
            System.out.println("不是字符串");
        }
    }
    //String API没有讲全---------会查API【电子政务】---没有外网
}


